package net.minecraft.world;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public enum DimensionType {
    OVERWORLD(0, "overworld", "", WorldProviderSurface.class),
    NETHER(-1, "the_nether", "_nether", WorldProviderHell.class),
    THE_END(1, "the_end", "_end", WorldProviderEnd.class);

    private final int id;
    private final String name;
    private final String suffix;
    private final Class<? extends WorldProvider> clazz;
    private boolean shouldLoadSpawn = false;

    private DimensionType(int idIn, String nameIn, String suffixIn, Class<? extends WorldProvider> clazzIn) {
        this.id = idIn;
        this.name = nameIn;
        this.suffix = suffixIn;
        this.clazz = clazzIn;
        this.shouldLoadSpawn = idIn == 0;
    }

    public int getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public String getSuffix() {
        return this.suffix;
    }

    public WorldProvider createDimension() {
        try {
            Constructor<? extends WorldProvider> constructor = this.clazz.getConstructor();
            return constructor.newInstance();
        } catch (NoSuchMethodException nosuchmethodexception) {
            throw new Error("Could not create new dimension", nosuchmethodexception);
        } catch (InvocationTargetException invocationtargetexception) {
            throw new Error("Could not create new dimension", invocationtargetexception);
        } catch (InstantiationException instantiationexception) {
            throw new Error("Could not create new dimension", instantiationexception);
        } catch (IllegalAccessException illegalaccessexception) {
            throw new Error("Could not create new dimension", illegalaccessexception);
        }
    }

    public static DimensionType getById(int id) {
        for (DimensionType dimensiontype : values()) {
            if (dimensiontype.getId() == id) {
                return dimensiontype;
            }
        }

        throw new IllegalArgumentException("Invalid dimension id " + id);
    }

    public boolean shouldLoadSpawn() {
        return this.shouldLoadSpawn;
    }

    public DimensionType setLoadSpawn(boolean value) {
        this.shouldLoadSpawn = value;
        return this;
    }

    private static Class<?>[] ENUM_ARGS = {int.class, String.class, String.class, Class.class};

    static {
        net.minecraftforge.common.util.EnumHelper.testEnum(DimensionType.class, ENUM_ARGS);
    }

    public static DimensionType register(String name, String suffix, int id, Class<? extends WorldProvider> provider, boolean keepLoaded) {
        String enum_name = name.replace(" ", "_").toLowerCase();
        DimensionType ret = net.minecraftforge.common.util.EnumHelper.addEnum(DimensionType.class, enum_name, ENUM_ARGS,
                id, name, suffix, provider);
        return ret.setLoadSpawn(keepLoaded);
    }
    //TODO: Unregister? There is no way to really delete a enum value...

    public static DimensionType byName(String p_193417_0_) {
        for (DimensionType dimensiontype : values()) {
            if (dimensiontype.getName().equals(p_193417_0_)) {
                return dimensiontype;
            }
        }

        throw new IllegalArgumentException("Invalid dimension " + p_193417_0_);
    }
}